#include <stdio.h>
#include <stdlib.h>
#include <libpq-fe.h>

int beginTransaction(PGconn *conn)
{
  PGresult *res = PQexec(conn, "BEGIN");
  int result = 0;

  if(PQresultStatus(res) == PGRES_COMMAND_OK) result = 1;
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int endTransaction(PGconn *conn)
{
  PGresult *res = PQexec(conn, "END");
  int result = 0;

  if(PQresultStatus(res) == PGRES_COMMAND_OK) result = 1;
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int testSelectAll(PGconn *conn)
{
  int result = 0;
  int i,j,nFields;

  PGresult *res = PQexec(conn, "SELECT * from pista");
  if(PQresultStatus(res)==PGRES_TUPLES_OK)
  {
    result = 1;
    nFields = PQnfields(res);

    for(i=0; i<PQntuples(res); i++)
    {
      printf("\n-----\n");
      for(j=0; j<nFields; j++)
      {
        printf("%s = %s\n",PQfname(res,j),PQgetvalue(res,i,j));
      }
    }
  }
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int testInsert(PGconn *conn)
{
  int result = 0;
  const char *params[5] = {"1000","<nome1000>",0,"1000","0,0"};

  PGresult *res = PQexecParams(conn,
        "INSERT INTO pista(id, nome, imagem, num_setores, posicao) values($1, $2, $3, $4, $5);",
        5,
        0,
        params,
        0,
        0,
        0);

  if(PQresultStatus(res) == PGRES_COMMAND_OK) result = 1;
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int testUpdate(PGconn *conn)
{
  int result = 0;
  const char *updateparams[2] = {"<nome_1000>","1000"};

  PGresult *res = PQexecParams(conn, 
        "UPDATE pista set nome=$1 where id=$2;",
        2,
        0,
        updateparams,
        0,
        0,
        0);

  if(PQresultStatus(res) == PGRES_COMMAND_OK) result = 1;
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int testDelete(PGconn *conn)
{
  int result = 0;
  const char *delparams[1] = {"1000"};

  PGresult *res = PQexecParams(conn, 
        "DELETE from pista where id=$1;",
        1,
        0,
        delparams,
        0,
        0,
        0);

  if(PQresultStatus(res) == PGRES_COMMAND_OK) result = 1;
  else fprintf(stderr,"BEGIN error: %s\n",PQerrorMessage(conn));

  PQclear(res);

  return result;
}

int main(void)
{
  PGconn *conn = 0;

  conn = PQconnectdb("host=localhost port=5432 dbname=kartfacil user=postgres password=facil123 sslmode=prefer connect_timeout=10");
  if(PQstatus(conn)!=CONNECTION_OK) goto ERR;

  if(!testInsert(conn)) goto ERR;
  if(!testSelectAll(conn)) goto ERR;

  if(!beginTransaction(conn)) goto ERR;
  if(!testUpdate(conn)) goto ERR;
  if(!endTransaction(conn)) goto ERR;

  if(!testSelectAll(conn)) goto ERR;
  if(!testDelete(conn)) goto ERR;

  PQfinish(conn);
  return 0;

ERR:
  printf("ERROR %s\n",PQerrorMessage(conn));
  if(conn) PQfinish(conn);
  return 1;
}
